package com.dictionary.cn.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.dictionary.cn.action.bean.DicResult;
import com.dictionary.cn.core.util.DictionarySpringContextUtils;

public class FilterToDicService implements Filter {
    
    private static final Logger LOG = LoggerFactory.getLogger(FilterToDicService.class);
    
    /**
     * 字典服务缓存
     */
    private Map<String, Method> dicMethodCache = new HashMap<String, Method>();
    
    public void destroy() {
    	
    }

    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain fc)
            throws IOException, ServletException {
    	HttpServletRequest request =(HttpServletRequest)arg0;
        HttpServletResponse response = (HttpServletResponse)arg1;
        LOG.info("---" + request.getRequestURI() +" action = "+ request.getParameter("action"));
        
        DicResult dr = excutection(request);
     // 设置headers参数
        response.setContentType("application/json;charset=UTF-8");
        // 去除缓存
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        LOG.info("-----------"+ JSONObject.toJSONString(dr) +"------------");
        PrintWriter pw = response.getWriter();
        pw.write(JSONObject.toJSONString(dr));
        pw.flush();
        pw.close();
    }

    public void init(FilterConfig arg0) throws ServletException {
    	LOG.info("初始化Controller开始!!");
        initDicAction(DictionaryAction.class, "getDic");   
        LOG.info("初始化Controller结束!!");
    }
    
    /**
     * 
     * <p>
     * 指定字典方法
     * </p>
     * @author xiaoruihu
     * @date 2015-6-3 上午10:37:26
     * @param request
     * @return
     */
    private DicResult excutection(HttpServletRequest request){
        String action = request.getParameter("action");
        DicResult dr = new DicResult();;
        if(this.dicMethodCache.containsKey(action)){
            try{
                Object o = this.dicMethodCache.get(action).invoke(DictionarySpringContextUtils.getBean("dictionaryAction"), request); 
                dr.setSuccess(true);
                dr.setMsg(o);
            }catch(InvocationTargetException e){
               LOG.error("执行【" + action +"】出现错误！！！" + e.getTargetException().getMessage());
               
               dr.setSuccess(false);
               dr.setMsg(e.getTargetException().getMessage());
            }catch(Exception e){
                LOG.error("执行【" + action +"】出现错误！！！", e);
                
                dr.setSuccess(false);
                dr.setMsg("actionError");
            }
            
        }else{
            dr.setSuccess(false);
            dr.setMsg("notExistAction");
        }
        return dr;
    }
    
    /**
     * 
     * <p>
     * 初始化字典服务，装载action
     * </p>
     * @author xiaoruihu
     * @date 2015-6-2 下午06:35:50
     */
    private void initDicAction(@SuppressWarnings("rawtypes") Class clazz, String pre, String... externMethodNames){
       Method[] methods =  clazz.getMethods();

       if(methods != null){
           for(Method mt : methods){
               
               String methodName = mt.getName();
               if(methodName.startsWith(pre)){
            	   LOG.info("注册了" + clazz.getName() + ":" + "methodName" + " Controller!");
                   this.dicMethodCache.put(methodName, mt);
                   continue;
               }
               
               if(externMethodNames != null){
                   for(String mName : externMethodNames){
                       if(methodName.equals(mName)){
                    	   LOG.info("注册了" + clazz.getName() + ":" + "methodName" + " Controller!");
                           this.dicMethodCache.put(methodName, mt);
                           break;
                       }
                   }
               }
           }
       }
    }
}
